# -*- coding: utf-8 -*-
import numpy as np

# 定义逻辑与、或、非数据
data_and = [
    [0, 0, 0],
    [0, 1, 0],
    [1, 0, 0],
    [1, 1, 1]
]
data_or = [
    [0, 0, 0],
    [0, 1, 1],
    [1, 0, 1],
    [1, 1, 1]
]
data_xor = [
    [0, 0, 0],
    [0, 1, 1],
    [1, 0, 1],
    [1, 1, 0]
]


def perceptron(data):
    """
    simulate perceptron to process logic AND, OR, XOR
    :param data: input data
    :return: NONE
    """
    w = np.array([1, 2])
    b = 0
    a = 1

    for i in range(10):
        for j in range(4):
            input_x = np.array(data[j][:2])
            y = 1 if np.dot(w, input_x) + b > 0 else 0
            t_value = np.array(data[j][2])

            delta_b = a * (t_value - y)
            delta_w = a * (t_value - y) * input_x

            print('epoch {} sample {}  [{} {} {} {} {} {} {}]'.format(
                i, j, w[0], w[1], b, y, delta_w[0], delta_w[1], delta_b
            ))

            b = b + delta_b
            w = w + delta_w


if __name__ == '__main__':
    print('logical and')
    perceptron(data_and)
    print('logical or')
    perceptron(data_or)
    print('logical xor')
    perceptron(data_xor)


'''
程序运行结果如下：
logical and
epoch 0 sample 0  [1 2 0 0 0 0 0]
epoch 0 sample 1  [1 2 0 1 0 -1 -1]
epoch 0 sample 2  [1 1 -1 0 0 0 0]
epoch 0 sample 3  [1 1 -1 1 0 0 0]
epoch 1 sample 0  [1 1 -1 0 0 0 0]
epoch 1 sample 1  [1 1 -1 0 0 0 0]
epoch 1 sample 2  [1 1 -1 0 0 0 0]
epoch 1 sample 3  [1 1 -1 1 0 0 0]
epoch 2 sample 0  [1 1 -1 0 0 0 0]
epoch 2 sample 1  [1 1 -1 0 0 0 0]
epoch 2 sample 2  [1 1 -1 0 0 0 0]
epoch 2 sample 3  [1 1 -1 1 0 0 0]
epoch 3 sample 0  [1 1 -1 0 0 0 0]
epoch 3 sample 1  [1 1 -1 0 0 0 0]
epoch 3 sample 2  [1 1 -1 0 0 0 0]
epoch 3 sample 3  [1 1 -1 1 0 0 0]
epoch 4 sample 0  [1 1 -1 0 0 0 0]
epoch 4 sample 1  [1 1 -1 0 0 0 0]
epoch 4 sample 2  [1 1 -1 0 0 0 0]
epoch 4 sample 3  [1 1 -1 1 0 0 0]
epoch 5 sample 0  [1 1 -1 0 0 0 0]
epoch 5 sample 1  [1 1 -1 0 0 0 0]
epoch 5 sample 2  [1 1 -1 0 0 0 0]
epoch 5 sample 3  [1 1 -1 1 0 0 0]
epoch 6 sample 0  [1 1 -1 0 0 0 0]
epoch 6 sample 1  [1 1 -1 0 0 0 0]
epoch 6 sample 2  [1 1 -1 0 0 0 0]
epoch 6 sample 3  [1 1 -1 1 0 0 0]
epoch 7 sample 0  [1 1 -1 0 0 0 0]
epoch 7 sample 1  [1 1 -1 0 0 0 0]
epoch 7 sample 2  [1 1 -1 0 0 0 0]
epoch 7 sample 3  [1 1 -1 1 0 0 0]
epoch 8 sample 0  [1 1 -1 0 0 0 0]
epoch 8 sample 1  [1 1 -1 0 0 0 0]
epoch 8 sample 2  [1 1 -1 0 0 0 0]
epoch 8 sample 3  [1 1 -1 1 0 0 0]
epoch 9 sample 0  [1 1 -1 0 0 0 0]
epoch 9 sample 1  [1 1 -1 0 0 0 0]
epoch 9 sample 2  [1 1 -1 0 0 0 0]
epoch 9 sample 3  [1 1 -1 1 0 0 0]
logical or
epoch 0 sample 0  [1 2 0 0 0 0 0]
epoch 0 sample 1  [1 2 0 1 0 0 0]
epoch 0 sample 2  [1 2 0 1 0 0 0]
epoch 0 sample 3  [1 2 0 1 0 0 0]
epoch 1 sample 0  [1 2 0 0 0 0 0]
epoch 1 sample 1  [1 2 0 1 0 0 0]
epoch 1 sample 2  [1 2 0 1 0 0 0]
epoch 1 sample 3  [1 2 0 1 0 0 0]
epoch 2 sample 0  [1 2 0 0 0 0 0]
epoch 2 sample 1  [1 2 0 1 0 0 0]
epoch 2 sample 2  [1 2 0 1 0 0 0]
epoch 2 sample 3  [1 2 0 1 0 0 0]
epoch 3 sample 0  [1 2 0 0 0 0 0]
epoch 3 sample 1  [1 2 0 1 0 0 0]
epoch 3 sample 2  [1 2 0 1 0 0 0]
epoch 3 sample 3  [1 2 0 1 0 0 0]
epoch 4 sample 0  [1 2 0 0 0 0 0]
epoch 4 sample 1  [1 2 0 1 0 0 0]
epoch 4 sample 2  [1 2 0 1 0 0 0]
epoch 4 sample 3  [1 2 0 1 0 0 0]
epoch 5 sample 0  [1 2 0 0 0 0 0]
epoch 5 sample 1  [1 2 0 1 0 0 0]
epoch 5 sample 2  [1 2 0 1 0 0 0]
epoch 5 sample 3  [1 2 0 1 0 0 0]
epoch 6 sample 0  [1 2 0 0 0 0 0]
epoch 6 sample 1  [1 2 0 1 0 0 0]
epoch 6 sample 2  [1 2 0 1 0 0 0]
epoch 6 sample 3  [1 2 0 1 0 0 0]
epoch 7 sample 0  [1 2 0 0 0 0 0]
epoch 7 sample 1  [1 2 0 1 0 0 0]
epoch 7 sample 2  [1 2 0 1 0 0 0]
epoch 7 sample 3  [1 2 0 1 0 0 0]
epoch 8 sample 0  [1 2 0 0 0 0 0]
epoch 8 sample 1  [1 2 0 1 0 0 0]
epoch 8 sample 2  [1 2 0 1 0 0 0]
epoch 8 sample 3  [1 2 0 1 0 0 0]
epoch 9 sample 0  [1 2 0 0 0 0 0]
epoch 9 sample 1  [1 2 0 1 0 0 0]
epoch 9 sample 2  [1 2 0 1 0 0 0]
epoch 9 sample 3  [1 2 0 1 0 0 0]
logical xor
epoch 0 sample 0  [1 2 0 0 0 0 0]
epoch 0 sample 1  [1 2 0 1 0 0 0]
epoch 0 sample 2  [1 2 0 1 0 0 0]
epoch 0 sample 3  [1 2 0 1 -1 -1 -1]
epoch 1 sample 0  [0 1 -1 0 0 0 0]
epoch 1 sample 1  [0 1 -1 0 0 1 1]
epoch 1 sample 2  [0 2 0 0 1 0 1]
epoch 1 sample 3  [1 2 1 1 -1 -1 -1]
epoch 2 sample 0  [0 1 0 0 0 0 0]
epoch 2 sample 1  [0 1 0 1 0 0 0]
epoch 2 sample 2  [0 1 0 0 1 0 1]
epoch 2 sample 3  [1 1 1 1 -1 -1 -1]
epoch 3 sample 0  [0 0 0 0 0 0 0]
epoch 3 sample 1  [0 0 0 0 0 1 1]
epoch 3 sample 2  [0 1 1 1 0 0 0]
epoch 3 sample 3  [0 1 1 1 -1 -1 -1]
epoch 4 sample 0  [-1 0 0 0 0 0 0]
epoch 4 sample 1  [-1 0 0 0 0 1 1]
epoch 4 sample 2  [-1 1 1 0 1 0 1]
epoch 4 sample 3  [0 1 2 1 -1 -1 -1]
epoch 5 sample 0  [-1 0 1 1 0 0 -1]
epoch 5 sample 1  [-1 0 0 0 0 1 1]
epoch 5 sample 2  [-1 1 1 0 1 0 1]
epoch 5 sample 3  [0 1 2 1 -1 -1 -1]
epoch 6 sample 0  [-1 0 1 1 0 0 -1]
epoch 6 sample 1  [-1 0 0 0 0 1 1]
epoch 6 sample 2  [-1 1 1 0 1 0 1]
epoch 6 sample 3  [0 1 2 1 -1 -1 -1]
epoch 7 sample 0  [-1 0 1 1 0 0 -1]
epoch 7 sample 1  [-1 0 0 0 0 1 1]
epoch 7 sample 2  [-1 1 1 0 1 0 1]
epoch 7 sample 3  [0 1 2 1 -1 -1 -1]
epoch 8 sample 0  [-1 0 1 1 0 0 -1]
epoch 8 sample 1  [-1 0 0 0 0 1 1]
epoch 8 sample 2  [-1 1 1 0 1 0 1]
epoch 8 sample 3  [0 1 2 1 -1 -1 -1]
epoch 9 sample 0  [-1 0 1 1 0 0 -1]
epoch 9 sample 1  [-1 0 0 0 0 1 1]
epoch 9 sample 2  [-1 1 1 0 1 0 1]
epoch 9 sample 3  [0 1 2 1 -1 -1 -1]
'''

'''
解释为什么这里的感知器代码无法完成异或功能？
我们这里使用的是阶越函数作为感知器，阶越函数是线性函数，不能划分非线性结果。
而异或功能的结果是无法线性可分的，所以我们这里的代码无法完成异或功能。
'''